package crypto

import (
	"fmt"
	"math/big"
)

func GenerateThreNew(N, f int) (thpk G1, thpks []G1, thsks []ZR, err error) {
	if f >= N || f < 1 {
		return G1{}, nil, nil, fmt.Errorf("f must be less than N and at least 1")
	}

	coeffs := make([]ZR, f+1)
	for i := 0; i <= f; i++ {
		var randZr ZR
		// SetRandom can now be called directly due to embedding.
		randZr.SetRandom()
		coeffs[i] = randZr
	}
	secret := coeffs[0]

	gen := GetG1()
	thpk = MulG1(&gen, &secret)

	thpks = make([]G1, N)
	thsks = make([]ZR, N)
	for i := 1; i <= N; i++ {
		x := big.NewInt(int64(i))
		sk_i := evalPolynomial(coeffs, x)
		thsks[i-1] = sk_i

		pk_i := MulG1(&gen, &sk_i)
		thpks[i-1] = pk_i
	}

	return thpk, thpks, thsks, nil
}

func evalPolynomial(coeffs []ZR, x *big.Int) ZR {
	var result ZR
	result.SetZero()

	var xZr ZR
	xZr.SetBigInt(x)

	for i := len(coeffs) - 1; i >= 0; i-- {
		result.Mul(&result, &xZr)
		result.Add(&result, &coeffs[i])
	}
	return result
}
